var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
const http = require('http');
const socketIo = require('socket.io');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var articlesRouter = require('./routes/articles');
var commentsRouter = require('./routes/comments');
var huaRouter = require('./routes/hua');
const confessionRouter = require('./routes/confession');
const dongtaiRouter = require('./routes/dongtai');
const uploadRouter = require('./routes/upload');
const campusCardRouter = require('./routes/campusCard');
const messagesRouter = require('./routes/messages');
const vipRouter = require('./routes/vip');
const aiRouter = require('./routes/ai');
let user='asxdasdasd'
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

app.use(cors());

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/articles', articlesRouter);
app.use('/comments', commentsRouter);
app.use('/hua', huaRouter);
app.use('/api/confessions', confessionRouter);
app.use('/dongtai', dongtaiRouter);
app.use('/upload', uploadRouter);
app.use('/api/campus-card', campusCardRouter);
app.use('/api/messages', messagesRouter);
app.use('/api/vip', vipRouter);
app.use('/api/ai', aiRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  console.log("🚀 ~ err:", err)
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

// 创建HTTP服务器
const server = http.createServer(app);

// 创建Socket.IO实例
const io = socketIo(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
});

// 存储在线用户
const onlineUsers = new Map();
// 存储群聊房间
const groupRooms = new Map();

// Socket.IO连接处理
io.on('connection', (socket) => {
  console.log('用户连接:', socket.id);

  // 用户登录
  socket.on('user_login', (userData) => {
    const { userId, username } = userData;
    onlineUsers.set(userId, {
      socketId: socket.id,
      username: username
    });
    socket.userId = userId;
    console.log(`用户 ${username} (${userId}) 已登录`);
    console.log('当前在线用户:', Array.from(onlineUsers.keys()));
  });

  // 加入群聊房间
  socket.on('join_group', (data) => {
    const { groupId, userId } = data;
    const roomName = `group_${groupId}`;
    
    socket.join(roomName);
    socket.currentGroup = groupId;
    
    // 记录群聊房间信息
    if (!groupRooms.has(groupId)) {
      groupRooms.set(groupId, new Set());
    }
    groupRooms.get(groupId).add(userId);
    
    console.log(`用户 ${userId} 加入群聊 ${groupId}`);
    console.log(`群聊 ${groupId} 当前成员:`, Array.from(groupRooms.get(groupId)));
  });

  // 离开群聊房间
  socket.on('leave_group', (data) => {
    const { groupId, userId } = data;
    const roomName = `group_${groupId}`;
    
    socket.leave(roomName);
    socket.currentGroup = null;
    
    // 从群聊房间记录中移除
    if (groupRooms.has(groupId)) {
      groupRooms.get(groupId).delete(userId);
      if (groupRooms.get(groupId).size === 0) {
        groupRooms.delete(groupId);
      }
    }
    
    console.log(`用户 ${userId} 离开群聊 ${groupId}`);
  });

  // 发送群聊消息
  socket.on('send_group_message', async (messageData) => {
    try {
      const { groupId, from, content, messageType } = messageData;
      
      console.log('WebSocket收到群聊消息:', { groupId, from, content, messageType });
      
      // 验证用户是否存在
      const { userModel, groupModel, groupMessageModel } = require('./model/model');
      const sender = await userModel.findById(from);
      const group = await groupModel.findById(groupId);
      
      if (!sender) {
        console.log('发送者不存在');
        socket.emit('group_message_sent', {
          success: false,
          message: '发送者不存在'
        });
        return;
      }
      
      if (!group) {
        console.log('群聊不存在');
        socket.emit('group_message_sent', {
          success: false,
          message: '群聊不存在'
        });
        return;
      }
      
      // 验证用户是否在群聊中
      if (!group.members.some(memberId => memberId.toString() === from)) {
        console.log('用户不在群聊中');
        socket.emit('group_message_sent', {
          success: false,
          message: '您不是该群聊的成员'
        });
        return;
      }
      
      // 保存群聊消息到数据库
      const newMessage = new groupMessageModel({
        groupId,
        from,
        content,
        messageType: messageType || 'text',
        time: new Date()
      });
      
      await newMessage.save();
      console.log('群聊消息保存成功:', newMessage._id);
      
      // 获取完整的消息信息（包含populated的from字段）
      const populatedMessage = await groupMessageModel.findById(newMessage._id)
        .populate('from', 'username avatarImage');
      
      // 更新群聊中其他成员的未读消息数
      const otherMembers = group.members.filter(memberId => memberId.toString() !== from);
      for (const memberId of otherMembers) {
        const currentUnread = group.memberUnreadCount.get(memberId.toString()) || 0;
        group.memberUnreadCount.set(memberId.toString(), currentUnread + 1);
      }
      await group.save();
      
      // 发送消息给群聊房间的所有成员
      const roomName = `group_${groupId}`;
      io.to(roomName).emit('receive_group_message', populatedMessage);
      console.log('群聊消息已发送给房间:', roomName);
      
      // 发送确认给发送者
      socket.emit('group_message_sent', {
        success: true,
        message: '群聊消息发送成功',
        data: populatedMessage
      });
      
    } catch (error) {
      console.error('WebSocket发送群聊消息错误:', error);
      socket.emit('group_message_sent', {
        success: false,
        message: '群聊消息发送失败'
      });
    }
  });

  // 发送消息
  socket.on('send_message', async (messageData) => {
    try {
      const { senderId, receiverId, content, messageType } = messageData;
      
      console.log('WebSocket收到消息:', { senderId, receiverId, content, messageType });
      
      // 验证用户是否存在
      const { userModel } = require('./model/model');
      const sender = await userModel.findById(senderId);
      const receiver = await userModel.findById(receiverId);
      
      if (!sender || !receiver) {
        console.log('用户不存在，创建临时用户');
        // 如果用户不存在，创建临时用户
        if (!sender) {
          const tempSender = new userModel({
            username: messageData.senderName || '临时用户',
            studentId: `TEMP_${senderId}`,
            password: '123456',
            schoolId: '688cb2ff5e9bdf7c861dcd90' // 使用默认学校ID
          });
          await tempSender.save();
          messageData.senderId = tempSender._id;
        }
        
        if (!receiver) {
          const tempReceiver = new userModel({
            username: messageData.receiverName || '临时用户',
            studentId: `TEMP_${receiverId}`,
            password: '123456',
            schoolId: '688cb2ff5e9bdf7c861dcd90' // 使用默认学校ID
          });
          await tempReceiver.save();
          messageData.receiverId = tempReceiver._id;
        }
      }
      
      // 保存消息到数据库
      const { MessageModel } = require('./model/model');
      const newMessage = new MessageModel({
        senderId: messageData.senderId,
        receiverId: messageData.receiverId,
        content,
        messageType: messageType || 'text',
        timestamp: new Date() // 确保时间戳正确
      });
      
      await newMessage.save();
      console.log('WebSocket消息保存成功:', newMessage._id);
      
      // 获取完整的消息信息（包含populated的senderId和receiverId）
      const populatedMessage = await MessageModel.findById(newMessage._id)
        .populate('senderId', 'username studentId avatarImage')
        .populate('receiverId', 'username studentId avatarImage');
      
      // 检查接收者是否在线
      const receiverSocket = onlineUsers.get(messageData.receiverId);
      
      if (receiverSocket) {
        // 发送给在线用户
        io.to(receiverSocket.socketId).emit('receive_message', populatedMessage);
        console.log('消息已发送给在线用户:', messageData.receiverId);
      } else {
        console.log('接收者不在线:', messageData.receiverId);
      }
      
      // 发送确认给发送者，同时发送完整的消息数据
      socket.emit('message_sent', {
        success: true,
        message: '消息发送成功',
        data: populatedMessage
      });
      
      // 同时发送receive_message事件给发送者，确保发送者也能看到自己的消息
      socket.emit('receive_message', populatedMessage);
      
    } catch (error) {
      console.error('WebSocket发送消息错误:', error);
      socket.emit('message_sent', {
        success: false,
        message: '消息发送失败'
      });
    }
  });

  // 用户正在输入
  socket.on('typing', (data) => {
    const { receiverId, isTyping } = data;
    const receiverSocket = onlineUsers.get(receiverId);
    
    if (receiverSocket) {
      io.to(receiverSocket.socketId).emit('user_typing', {
        senderId: socket.userId,
        isTyping
      });
    }
  });

  // 断开连接
  socket.on('disconnect', () => {
    if (socket.userId) {
      onlineUsers.delete(socket.userId);
      console.log(`用户 ${socket.userId} 已断开连接`);
    }
  });
});

// 将io实例添加到app中，以便在路由中使用
app.set('io', io);

module.exports = { app, server };
